<?php


namespace app\common\controller;

use think\Db;

/**
 * 联邦快递接口
 * Class Fedex
 * @package app\common\controller
 */
class Fedex
{
    private $url = "https://apis.fedex.com/";//正式
//    private $client_id = 'l765e2ed2af5b44664a5f9024f891ebd4a';
//    private $client_secret = 'c9a436b0cc794de4b6e595ffaacc0882';
//    private $account_number = 734942430;//账号
//    private $shipper_postal_code = 92821;//发货地邮编
//    private $shipper_country_code = 'US';//发货地简码

//    private $url = "https://apis-sandbox.fedex.com/";//沙盒
//    private $client_id = 'l70d75ab9efc0b406a95271c97450e2a8c';
//    private $client_secret = '79c931f453f946b3be99233b35e7ec3d';
//    private $account_number = 740561073;//账号
//    private $shipper_postal_code = 92821;//发货地邮编
//    private $shipper_country_code = 'US';//发货地简码
//    private $shipper_person_name = 'SHIPPER NAME';//发货人姓名
//    private $shipper_phone_number = '1234567890';//发货人手机号
//    private $shipper_street_lines = 'SHIPPER STREET LINE 1';//发货详细地址
//    private $shipper_city = 'HARRISON';//发货城市
//    private $shipper_state_or_province_code = 'AR';//发货州省代码

    private $client_id = '';
    private $client_secret = '';
    private $account_number = '';//账号
    private $shipper_postal_code = '';//发货地邮编
    private $shipper_country_code = '';//发货地简码

//    private $shipper_person_name = '';//发货人姓名
//    private $shipper_phone_number = '';//发货人手机号
//    private $shipper_street_lines = '';//发货详细地址
//    private $shipper_city = '';//发货城市
//    private $shipper_state_or_province_code = '';//发货州省代码
    /**
     * 初始化参数
     */
    public function __construct()
    {
        //从后台配置中获取账号信息
        $config = Db::name('shipping_method')->where('id',1)->value('config');
        $config = json_decode($config,true);
        $this->client_id = $config['client_id'];
        $this->client_secret = $config['client_secret'];
        $this->account_number = $config['account_number'];
        $this->shipper_postal_code = $config['shipper_postal_code'];
        $this->shipper_country_code = $config['shipper_country_code'];

//        $this->shipper_person_name = $config['shipper_person_name'];//发货人姓名
//        $this->shipper_phone_number = $config['shipper_phone_number'];//发货人手机号
//        $this->shipper_street_lines = $config['shipper_street_lines'];//发货详细地址
//        $this->shipper_city = $config['shipper_city'];//发货城市
//        $this->shipper_state_or_province_code = $config['shipper_state_or_province_code'];//发货州省代码
    }

    /**
     * 获取token
     */
    public function get_token($url,$client_id,$client_secret){
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $url.'/oauth/token',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => 'grant_type=client_credentials&client_id='.$client_id.'&client_secret='.$client_secret,
            CURLOPT_HTTPHEADER => array(
                'Content-Type: application/x-www-form-urlencoded'
            ),
        ));
        $response = curl_exec($curl);
        curl_close($curl);
        return $response;
    }

    public function send_host($type,$json_data){
        $url = $this->url;
        $client_id = $this->client_id;
        $client_secret = $this->client_secret;
        $token = self::get_token($url,$client_id,$client_secret);
        $token = json_decode($token,true);
        if(!isset($token['access_token'])){
            return ['code'=>10,'msg'=>'获取Fedex token失败'];
        }

        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $url.$type,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS =>$json_data,
            CURLOPT_HTTPHEADER => array(
                'Content-Type: application/json',
                'X-locale:en_US',
                'Authorization: bearer '.$token['access_token']
            ),
        ));
        $response_old = curl_exec($curl);
        curl_close($curl);
        $response = json_decode($response_old,true);
//        halt($response);
        if(isset($response['errors'])){
            return ['code'=>10,'msg'=>$response['errors'][0]['message']];
        }else{
            return ['code'=>20,'data'=>$response];
        }
    }
    /**
     * 获取fedex运费
     */
    public function get_fedex_freight($postalCode,$countryCode,$cart,$service){
//        $postalCode = 75063;//收货地邮编
//        $countryCode = 'US';//收货地简码
//        $weight = 151;//重量
        if(empty($postalCode)){
            return ['code'=>10,'msg'=>'收货地邮编不能为空'];
        }
        if(empty($countryCode)){
            return ['code'=>10,'msg'=>'收货地简码不能为空'];
        }
        if(empty($cart)){
            return ['code'=>10,'msg'=>'商品为空'];
        }
        if(empty($service)){
            return ['code'=>10,'msg'=>'请选择运输类型'];
        }

        $arr = [];
        $totalPackageCount = 0;
        $totalWeight = 0;
        foreach ($cart as $k=>$v){
            $arr[$k]['groupPackageCount']=$v['total_num'];
            $arr[$k]['weight']['units']="LB";
            $arr[$k]['weight']['value']=$v['weight'];
            $arr[$k]['dimensions']['length']=ceil($v['long']);
            $arr[$k]['dimensions']['width']=ceil($v['wide']);
            $arr[$k]['dimensions']['height']=ceil($v['high']);
            $arr[$k]['dimensions']['units']="IN";

            $totalPackageCount += $v['total_num'];
            $totalWeight += $v['weight'];
        }
//        halt($arr);
        $arr_json = json_encode($arr);

        $json_data = '{
  "accountNumber": {
    "value": "'.$this->account_number.'"
  },
  "requestedShipment": {
    "shipper": {
      "address": {
        "postalCode": '.$this->shipper_postal_code.',
        "countryCode": "'.$this->shipper_country_code.'"
      }
    },
    "recipient": {
      "address": {
        "postalCode": '.$postalCode.',
        "countryCode": "'.$countryCode.'"
      }
    },
    "serviceType":"'.$service.'",
    "pickupType": "DROPOFF_AT_FEDEX_LOCATION",
    "rateRequestType": [
      "LIST"
    ],
    "requestedPackageLineItems": '.$arr_json.',
    "packagingType": "YOUR_PACKAGING",
    "totalPackageCount": '.$totalPackageCount.',
    "totalWeight": '.$totalWeight.'
  }
}';
//        echo $json_data;exit;
        $response = $this->send_host('/rate/v1/rates/quotes',$json_data);
//        halt($response);
        if($response['code'] == 10){
            return $response;
        }
//        halt($response);
        $new_arr = [];
        foreach ($response['data']['output']['rateReplyDetails'] as $v){
            $new_arr[$v['serviceType']] = $v['ratedShipmentDetails'][0]['totalBaseCharge'];
        }
//        print_r($new_arr);exit;
        $freight = $new_arr[$service];
        return ['code'=>20,'msg'=>'查询成功','freight'=>$freight];
    }

    /**
     * 根据跟踪号获取物流详情
     */
    public function get_fedex_info($tracking_no){
        if(empty($tracking_no)){
            return ['code'=>10,'msg'=>'Tracking no.不能为空'];
        }

        $json_data = '{
  "trackingInfo": [
    {
      "trackingNumberInfo": {
        "trackingNumber": "'.$tracking_no.'"
      }
    }
  ],
  "includeDetailedScans": true
}';
//        echo $json_data;exit;
        $response = $this->send_host('/track/v1/trackingnumbers',$json_data);
//        halt($response);
        if($response['code'] == 10){
            return $response;
        }
        if(!isset($response['data']['output']['completeTrackResults'][0]['trackResults'][0]['scanEvents'])){
            return ['code'=>10,'msg'=>$response['data']['output']['completeTrackResults'][0]['trackResults'][0]['error']['message']];
        }
        $list = $response['data']['output']['completeTrackResults'][0]['trackResults'][0]['scanEvents'];
        return ['code'=>20,'msg'=>'查询成功','data'=>$list];
    }

    /**
     * 生成物流单，并打印
     */
    public function create_ship($goods,$address){
        $all_weight = 0;
        foreach ($goods as $k=>$v){
            $goods_weight = $v['goods_weight']*$v['total_num'];
            $all_weight += $goods_weight;
        }

        $json_data = '{
  "labelResponseOptions": "URL_ONLY",
  "requestedShipment": {
    "shipper": {
      "contact": {
        "personName": "'.$this->shipper_person_name.'",
        "phoneNumber": '.$this->shipper_phone_number.'
      },
      "address": {
        "streetLines": [
          "'.$this->shipper_street_lines.'"
        ],
        "city": "'.$this->shipper_city.'",
        "stateOrProvinceCode": "'.$this->shipper_state_or_province_code.'",
        "postalCode": '.$this->shipper_postal_code.',
        "countryCode": "'.$this->shipper_country_code.'"
      }
    },
    "recipients": [
      {
        "contact": {
          "personName": "'.$address['first_name'].' '.$address['last_name'].'",
          "phoneNumber": '.$address['phone_number'].',
        },
        "address": {
          "streetLines": [
            "'.$address['detail'].'"
          ],
          "city": "'.$address['city'].'",
          "stateOrProvinceCode": "'.$address['state_code'].'",
          "postalCode": '.$address['postal_code'].',
          "countryCode": "'.$address['country_code'].'"
        }
      }
    ],
    "shipDatestamp": "'.date('Y-m-d H:i:s').'",
    "serviceType": "'.$address['service'].'",
    "packagingType": "YOUR_PACKAGING",
    "pickupType": "USE_SCHEDULED_PICKUP",
    "blockInsightVisibility": false,
    "shippingChargesPayment": {
      "paymentType": "SENDER"
    },
    "shipmentSpecialServices": {
      "specialServiceTypes": [
        "RETURN_SHIPMENT"
      ],
      "returnShipmentDetail": {
        "returnType": "PRINT_RETURN_LABEL"
      }
    },
    "labelSpecification": {
      "imageType": "PDF",
      "labelStockType": "PAPER_85X11_TOP_HALF_LABEL"
    },
    "requestedPackageLineItems": [
      {
        "weight": {
          "value": '.$all_weight.',
          "units": "LB"
        }
      }
    ]
  },
  "accountNumber": {
    "value": "'.$this->account_number.'"
  }
}';
//        echo $json_data;exit;
        $response = $this->send_host('/ship/v1/shipments',$json_data);
        halt($response);
        if($response['code'] == 10){
            return $response;
        }
        $list = $response['data']['output']['completeTrackResults'][0]['trackResults'][0]['scanEvents'];
        return ['code'=>20,'msg'=>'查询成功','data'=>$list];
    }
    public function create_ship_test(){


        $json_data = '{
  "labelResponseOptions": "URL_ONLY",
  "requestedShipment": {
    "shipper": {
      "contact": {
        "personName": "SHIPPER NAME",
        "phoneNumber": 1234567890,
        "companyName": "Shipper Company Name"
      },
      "address": {
        "streetLines": [
          "SHIPPER STREET LINE 1"
        ],
        "city": "HARRISON",
        "stateOrProvinceCode": "AR",
        "postalCode": 72601,
        "countryCode": "US"
      }
    },
    "recipients": [
      {
        "contact": {
          "personName": "RECIPIENT NAME",
          "phoneNumber": 1234567890,
          "companyName": "Recipient Company Name"
        },
        "address": {
          "streetLines": [
            "RECIPIENT STREET LINE 1",
            "RECIPIENT STREET LINE 2"
          ],
          "city": "Collierville",
          "stateOrProvinceCode": "TN",
          "postalCode": 38017,
          "countryCode": "US"
        }
      }
    ],
    "shipDatestamp": "2023-03-24",
    "serviceType": "PRIORITY_OVERNIGHT",
    "packagingType": "FEDEX_ENVELOPE",
    "pickupType": "USE_SCHEDULED_PICKUP",
    "blockInsightVisibility": false,
    "shippingChargesPayment": {
      "paymentType": "SENDER"
    },
    "shipmentSpecialServices": {
      "specialServiceTypes": [
        "RETURN_SHIPMENT"
      ],
      "returnShipmentDetail": {
        "returnType": "PRINT_RETURN_LABEL"
      }
    },
    "labelSpecification": {
      "imageType": "PDF",
      "labelStockType": "PAPER_85X11_TOP_HALF_LABEL"
    },
    "requestedPackageLineItems": [
      {
        "weight": {
          "value": 1,
          "units": "LB"
        }
      }
    ]
  },
  "accountNumber": {
    "value": "'.$this->account_number.'"
  }
}';
//        echo $json_data;exit;
        $response = $this->send_host('/ship/v1/shipments',$json_data);
        halt($response);
        if($response['code'] == 10){
            return $response;
        }
        $list = $response['data']['output']['completeTrackResults'][0]['trackResults'][0]['scanEvents'];
        return ['code'=>20,'msg'=>'查询成功','data'=>$list];
    }
}